# coding=utf-8
"""
author = jamon
"""
import asyncio
from abc import ABC

from obespoir.base.ob_handler import BaseHandler, RegisterEvent
from obespoir.share.espoir_log import global_log as logger, log_record

from package.msg_const import MsgID, ResponseStatus
from package.game_const import RoomType
from server.service.game_manager import GameManager, ReadyStatus
from server.service.room.base_room import GameType
from server.service.user_manager import UserManager


class ServiceHandler(BaseHandler, ABC):

    @property
    def user_id(self):
        return UserManager().get_user_id_by_session(self.session_id)


@RegisterEvent(MsgID.OFFLINE, need_return=False)
class OfflineHandler(ServiceHandler):
    @log_record
    async def execute(self, *args, **kwargs):
        logger.info("offline", args=args, kwargs=kwargs)
        pass
        return {"code": 200}


@RegisterEvent(MsgID.HEARTBEAT, need_return=True)
class HeartBeatHandler(ServiceHandler):

    async def execute(self, *args, **kwargs):
        logger.info("heartbeat", args=args, kwargs=kwargs)
        pass
        return {"code": 200}


@RegisterEvent(MsgID.LOGIN)
class LoginHandler(ServiceHandler):

    async def execute(self, *args, **kwargs):
        logger.info("login_handler start", args=args, kwargs=kwargs)
        user_name = self.params.get("user_name", "")
        passwd = self.params.get("passwd", "")
        if not user_name or not passwd:
            return {}
        # ...
        user_id = str(hash(user_name))
        UserManager().update_session(self.session_id, user_id, user_name)
        return {"code": ResponseStatus.SUCCESS,
                "data": {"user_id": user_id, "session_id": self.session_id,
                         "desc": "恭喜，登录接口测试通过~"}}


@RegisterEvent(MsgID.CREATE_ROOM, need_return=True)
class CreateRoomHandler(ServiceHandler):
    @log_record
    async def execute(self, *args, **kwargs):
        game_type = self.params.get("game_type", GameType.SINGLE)
        room_type = self.params.get("room_type", RoomType.MATCH)
        game_id = GameManager().create_room(self.user_id, game_type, room_type)
        return {"code": 200, "data": {"game_id": game_id}}


@RegisterEvent(MsgID.DISMISS_ROOM, need_return=True)
class DismissRoomHandler(ServiceHandler):
    @log_record
    async def execute(self, *args, **kwargs):
        # ...
        pass
        return {"code": 200, "data": {"desc": "恭喜，解散房间接口测试通过~"}}


@RegisterEvent(MsgID.OTHER_LOGIN, need_return=True)
class OtherLoginHandler(ServiceHandler):
    @log_record
    async def execute(self, *args, **kwargs):
        # ...
        pass
        return {"code": 200,
                "data": {"desc": "恭喜，其他设备登录接口测试通过~"}}


@RegisterEvent(MsgID.ENTER_ROOM, need_return=True)
class EnterRoomHandler(ServiceHandler):
    @log_record
    async def execute(self, *args, **kwargs):
        # ...
        pass
        return {"code": 200, "data": {"desc": "恭喜，进入房间接口测试通过~"}}


@RegisterEvent(MsgID.ENTER_MATCH_ROOM, need_return=True)
class EnterMatchRoomHandler(ServiceHandler):
    @log_record
    async def execute(self, *args, **kwargs):
        game_type = self.params.get("game_type", GameType.SINGLE)
        # ...
        GameManager().join_match_room(self.user_id, game_type)
        return {"code": 200, "data": {"desc": "恭喜，进入房间接口测试通过~"}}


@RegisterEvent(MsgID.GAME_OPERATION, need_return=True)
class GameOperationHandler(ServiceHandler):
    @log_record
    async def execute(self, *args, **kwargs):
        # op = self.params.get("op", {})
        op = self.params
        GameManager().add_op(self.user_id, op)
        return {"code": 200, "data": {"desc": "恭喜，游戏操作接口测试通过~"}}


@RegisterEvent(MsgID.GAME_OVER, need_return=True)
class GameOverHandler(ServiceHandler):
    @log_record
    async def execute(self, *args, **kwargs):
        try:
            is_win = self.params.get("is_win", False)
            game_id = GameManager().set_ready_status(
                self.user_id, ReadyStatus.GAME_OVER)
            is_over = GameManager().check_game_over(game_id)
            if is_over:
                # TODO通知所有玩家游戏结束
                await GameManager().game_over(game_id, is_win=is_win)
        except Exception:  # noqa
            pass
        return {"code": 200, "data": {"desc": "恭喜，游戏结束接口测试通过~"}}


@RegisterEvent(MsgID.SET_READY, need_return=True)
class SetReadyHandler(ServiceHandler):
    @log_record
    async def execute(self, *args, **kwargs):
        game_id = GameManager().set_ready_status(
            self.user_id, ReadyStatus.READY)
        is_start = GameManager().check_start_game(game_id)
        logger.info("start_game", game_id=game_id, is_start=is_start)
        if is_start:
            # 通知所有玩家游戏开始
            asyncio.create_task(GameManager().start_game(game_id))
        return {"code": 200,
                "data": {"desc": "恭喜，设置准备状态接口测试通过~"}}
